//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Foundation
import Testing
import SWBUtil
import SWBCore
import SWBTestSupport

@Suite(.enabled(if: Diagnostic.libRemarksAvailable, "Skipping because libRemarks.dylib is not available."))
fileprivate struct OptimizationRemarksTests: CoreBasedTests {
    let xcode: InstalledXcode
    let infoLookup: any PlatformInfoLookup

    init() async throws {
        self.xcode = try await InstalledXcode.currentlySelected()
        self.infoLookup = try await Self.makeCore()
    }

    fileprivate func compileObjectFileWithRemarks(path basePath: Path, useSwift: Bool, infoLookup: any PlatformInfoLookup) async throws -> Path {
        let buildDir = basePath.join("build")
        let srcDir = basePath.join("src")
        try localFS.createDirectory(srcDir, recursive: true)
        try localFS.createDirectory(buildDir, recursive: true)
        let objectPath = buildDir.join("source.o")
        let target = BuildVersion.Platform.macOS.targetTripleString(arch: "x86_64", deploymentTarget: Version(10, 15), infoLookup: infoLookup)

        if useSwift {
            let sourcePath = srcDir.join("source.swift")
            try localFS.write(sourcePath, contents: "public func callee() -> Int { return 0 }\npublic func favorite() -> Int { return  callee()}\n")

            _ = try await xcode.xcrun(["-sdk", "macosx", "swiftc", "-target", target, "-module-name", "swiftremarks", "-o", objectPath.str, "-c", sourcePath.str, "-save-optimization-record=bitstream", "-O", "-wmo", "-suppress-warnings"])
        } else {
            let sourcePath = srcDir.join("source.c")
            try localFS.write(sourcePath, contents: "int main() { return 0; }\n")

            _ = try await xcode.xcrun(["-sdk", "macosx", "clang", "-target", target, "-o", objectPath.str, "-c", sourcePath.str, "-fsave-optimization-record=bitstream", "-w"])
        }
        return objectPath
    }

    /// Test that optimization remarks generated by clang are supported.
    @Test
    func optimizationRemarksClang() async throws {
        try await withTemporaryDirectory { tmpDir -> Void in
            let objectFile = try await compileObjectFileWithRemarks(path: tmpDir, useSwift: false, infoLookup: infoLookup)
            let diagnostics = try Diagnostic.remarks(forObjectPath: objectFile, fs: localFS, workingDirectory: .root)
            #expect(!diagnostics.isEmpty)
            #expect(diagnostics.allSatisfy { diag in return diag.behavior == .remark })
        }
    }

    /// Test that optimization remarks generated by swift are supported.
    @Test
    func optimizationRemarksSwift() async throws {
        try await withTemporaryDirectory { tmpDir -> Void in
            let objectFile = try await compileObjectFileWithRemarks(path: tmpDir, useSwift: true, infoLookup: infoLookup)
            let diagnostics = try Diagnostic.remarks(forObjectPath: objectFile, fs: localFS, workingDirectory: .root)
            #expect(!diagnostics.isEmpty)
            #expect(diagnostics.allSatisfy { diag in return diag.behavior == .remark })
        }
    }
}
